Skip to content

Return SubSequence from SQLCommenter.getFirstWord to avoid per-inject substring#11736

Open
dougqh wants to merge 4 commits into
masterfrom
dougqh/sqlcommenter-getfirstword-subseq
Open

Return SubSequence from SQLCommenter.getFirstWord to avoid per-inject substring#11736
dougqh wants to merge 4 commits into
masterfrom
dougqh/sqlcommenter-getfirstword-subseq

Conversation

@dougqh

@dougqh dougqh commented Jun 24, 2026

Copy link
Copy Markdown
Contributor

What This Does

Updates SQLCommenter.getFirstWord to return a SubSequence instead of a sub-String.
By using SubSequence, we avoid the sub-string allocation and often the SubSequence will be optimized away completely via escape analysis.

Motivation

Reduce work in application threads
Reduce JDBC integration allocation

Additional Notes

SQLCommenter.getFirstWord returns a zero-copy SubSequence instead of sql.substring(...). Its result is only consumed by startsWith("{") / equalsIgnoreCase("call") in inject, so the per-inject substring allocation was pure waste. The returned view carries a "transient — do not retain" warning (it pins its backing String).

It also carries SubSequence.startsWith/equalsIgnoreCase (retracted from #10640 so they land with their motivating consumer rather than as speculative API).

Measured — SQLCommenterGetFirstWordBenchmark (JDK 17, @Threads(8), @Fork(5), -prof gc)

throughput gc.alloc.rate.norm
before (substring) 258.1M ± 21.0M ops/s 48 B/op
after (SubSequence) 508.0M ± 21.6M ops/s ~0 (10⁻⁴)

Escape analysis fully elides the view in the transient consumption: 48 B/op → ~0, ~2× throughput. (The win is contingent on non-escape — confirming why the view must not be retained.)

🤖 Generated with Claude Code

@dougqh dougqh added tag: performance Performance related changes tag: no release notes Changes to exclude from release notes type: refactoring inst: jdbc JDBC instrumentation tag: ai generated Largely based on code generated by an AI or LLM labels Jun 24, 2026
@dd-octo-sts

dd-octo-sts Bot commented Jun 24, 2026

Copy link
Copy Markdown
Contributor

🟢 Java Benchmark SLOs — All performance SLOs passed

Suite Status
Startup 🟢 pass

SLO thresholds are defined here based on automatically generated metrics. A warning is raised when results are within 5% of the threshold.

PR vs. master results
Scenario Candidate master Δ (95% CI of mean)
startup:insecure-bank:iast:Agent 13.91 s 13.95 s [-1.1%; +0.5%] (no difference)
startup:insecure-bank:tracing:Agent 12.88 s 13.05 s [-2.0%; -0.5%] (maybe better)
startup:petclinic:appsec:Agent 16.92 s 17.10 s [-5.4%; +3.3%] (no difference)
startup:petclinic:iast:Agent 17.38 s 17.39 s [-1.1%; +1.0%] (no difference)
startup:petclinic:profiling:Agent 16.97 s 17.39 s [-6.7%; +1.9%] (no difference)
startup:petclinic:sca:Agent 17.47 s 16.90 s [-1.1%; +7.8%] (no difference)
startup:petclinic:tracing:Agent 16.05 s 16.60 s [-7.4%; +0.7%] (no difference)

Commit: 2f648c75 · CI Pipeline · Benchmarking Platform UI


Load and DaCapo benchmarks can be triggered manually in the GitLab pipeline. Results will appear in the Benchmarking Platform UI after completion.

@dougqh

dougqh commented Jun 25, 2026

Copy link
Copy Markdown
Contributor Author

Benchmark results (zulu-17, JDK 17.0.7, @Threads(8), @Fork(5), -prof gc)

SQLCommenterGetFirstWordBenchmark.firstWordCheck:

throughput gc.alloc.rate.norm
before (substring) 258.1M ± 21.0M ops/s 48 B/op
after (SubSequence) 508.0M ± 21.6M ops/s ~0 B/op (10⁻⁴)

The SubSequence view is escape-analysis–elided in the transient firstWord check, so the old substring's 48 B/op (a String + its backing array) drops to ~0 and throughput rises ~2× at @Threads(8). @Fork(5) tightens the earlier bimodal @Fork(2) spread. Benchmark Javadoc refreshed in 89ca7b8.

dougqh and others added 4 commits June 29, 2026 11:06
…comparisons)

These are the ops a real classification parse needs but CharSequence lacks —
surfaced by porting SQLCommenter.getFirstWord (firstWord.startsWith("{"),
firstWord.equalsIgnoreCase("call")). Lets transient parse views be compared
without materializing a String. + JUnit 5 tests.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
… substring

getFirstWord's result is only consumed by startsWith("{") and
equalsIgnoreCase("call"), so materializing a substring on every inject() was
pure waste. Return a zero-copy SubSequence view instead and use its
startsWith/equalsIgnoreCase. Behavior is unchanged (91 SQLCommenterTest cases
pass); the test compares getFirstWord(sql).toString().

This is the motivating consumer for SubSequence.startsWith/equalsIgnoreCase
(retracted from #10640 and carried here so they land with their use case).

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Benchmarks the getFirstWord first-word scan, consuming the result via the real
transient pattern (startsWith, returning the boolean) so EA isn't faked away.
@threads(8), @fork(2), -prof gc: the old substring allocated 48 B/op per call;
the SubSequence view is fully EA-elided (~0 B/op), ~1.6x throughput. Numbers in
the class Javadoc.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
zulu-17 @fork(5), -prof gc: 258.1M -> 508.0M ops/s (~2x), 48 -> ~0 B/op.
@fork(5) tightens the earlier bimodal @fork(2) spread.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
@dougqh dougqh force-pushed the dougqh/sqlcommenter-getfirstword-subseq branch from 89ca7b8 to 2f648c7 Compare June 29, 2026 15:10
@dougqh dougqh marked this pull request as ready for review June 29, 2026 17:04
@dougqh dougqh requested review from a team as code owners June 29, 2026 17:04
@dougqh dougqh requested review from ygree and removed request for a team June 29, 2026 17:04
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

inst: jdbc JDBC instrumentation tag: ai generated Largely based on code generated by an AI or LLM tag: no release notes Changes to exclude from release notes tag: performance Performance related changes type: refactoring

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant